<template>
	<div class="g-upload-image">
		<vue-scroll @handle-scroll="handlePageScroll">
			<a-checkbox-group :value="props.checkedList" class="card-wrap" @change="onCheckedChange">
				<ul class="g-upload-image-list">
					<!-- 图片列表 -->
					<li
						:key="item?.id || index"
						v-for="(item, index) in value"
						class="g-upload-image-list-item"
						:class="[activeIndex === index && 'active']"
						:style="{ width: style.width, cursor: closePreview ? 'default' : 'pointer' }"
						@click.stop="onClickItem(item, index)"
					>
						<!-- 图片盒子 -->
						<div class="g-upload-image-item-wrap" :style="style">
							<template v-if="item.status === 'loading'">
								<div class="icon-loader">
									<i class="iconfont icon-loader-line"></i>
								</div>
							</template>
							<template v-else>
								<div v-if="value.length && !readonly" class="g-upload-image-operation">
									<!-- 修改 -->
									<label v-if="showUpdateIcon" @click.stop>
										<i class="iconfont icon-edit-line" @click.stop="onUpdateImage(item, index)"></i>
										<input
											id="g-upload-image-input"
											v-if="!disabledUpdateUpload"
											class="g-upload-image-input"
											type="file"
											@change.stop="onFileChange($event, index)"
										/>
									</label>
									<i v-if="showDeleteIcon" class="iconfont icon-delete-bin-line" @click.stop="onRemoveImage(item, index)"></i>
								</div>
							</template>
							<!-- 图片 -->

							<img class="g-upload-image-img" :src="item?.imageUrl" alt="" />
							<!-- 复选框 -->
							<div v-show="showCheckbox" :show-checkbox-hover="showCheckboxHover && !readonly" class="g-upload-image-checkbox" @click.stop>
								<a-checkbox :id="'' + item.id" :value="item.id"></a-checkbox>
								<!-- <a-checkbox v-model:checked="check" /> -->
							</div>
						</div>
						<!-- 名称 -->
						<div v-if="showName" class="g-upload-image-name">{{ item.personName }}</div>
					</li>
					<!-- 新增 -->
					<label v-if="showAdd && (count === -1 || value.length < count)" class="g-upload-image-wrap" :style="style">
						<div class="g-upload-image-add">
							<div v-if="loading" class="icon-loader">
								<i class="iconfont icon-loader-line"></i>
							</div>
							<div v-else class="icon-add">
								<i class="iconfont icon-add-line"></i>
								<p v-if="placeholder">{{ placeholder }}</p>
							</div>
						</div>
						<input class="g-upload-image-input" type="file" @change="onFileChange" />
					</label>
				</ul>
			</a-checkbox-group>
		</vue-scroll>
	</div>
	<global-alarm-modal ref="alarmModalRef" :hide-info="true"></global-alarm-modal>
</template>

<script setup lang="ts">
import { isDpi } from '@/global-utils/check';
import { Form, message } from 'ant-design-vue';
import { CheckboxValueType } from 'ant-design-vue/es/checkbox/interface';
import { computed, ref } from 'vue';
import { BoxManageApi } from '@/view-modules/config-manage/api';
import { ModuleType, UploadImageProps, FileList } from './GlobalImgListUploadConfig';
import GlobalAlarmModal from '../GlobalAlarmModal/GlobalAlarmModal.vue';

const props = withDefaults(defineProps<UploadImageProps>(), {
	value: () => [],
	showAdd: true,
	showName: false,
	placeholder: '',
	showUpdateIcon: true,
	showDeleteIcon: true,
	disabledUpdateUpload: false,
	disabledDelete: false,
	size: 'middle',
	activeIndex: -1,
	count: -1,
	maxFileSize: -1,
	accept: 'png,jpg',
	dpi: undefined,
	maxDpi: undefined,
	// eslint-disable-next-line no-use-before-define
	moduleType: ModuleType.SYSTEM,
	showCheckbox: false,
	readonly: false,
	closePreview: true,
	showCheckboxHover: false,
	boxSerial: null,
	checkedList: () => [],
	beforeUpload: () => true,
	beforeAddFileList: (file: FileList) => file
});
const emit = defineEmits([
	'update:value',
	'update:checkedList',
	'on-click-item',
	'on-success',
	'on-error',
	'on-remove',
	'on-update',
	'on-checked-change'
]);

const formItemContext = Form.useInjectFormItemContext();

const style = computed(() => {
	return {
		width: props.size === 'small' ? '60px' : props.size === 'middle' ? '100px' : '120px',
		height: props.size === 'small' ? '60px' : props.size === 'middle' ? '100px' : '120px'
	};
});

// 选中的复选框
const onCheckedChange = (checkedValue: CheckboxValueType[]): void => {
	emit('update:checkedList', checkedValue);
	emit('on-checked-change', checkedValue);
};
const headerBottomBorderColor = ref('transparent');

const handlePageScroll = (vertical: Record<string, any>): void => {
	headerBottomBorderColor.value = vertical.scrollTop > 10 ? '#20305b' : 'transparent';
};
// 点击图片
const alarmModalRef = ref<InstanceType<typeof GlobalAlarmModal>>();
/**
 * 预览图片
 * @param item
 * @param index
 */
const onPreview = (item: FileList): void => {
	const data = [
		{
			id: item.id,
			type: 'image',
			image: item.imageUrl
		}
	] as any[];
	alarmModalRef.value?.openModal(data);
};
const onClickItem = (item: FileList, index: number): void => {
	if (item.disabled) {
		return;
	}
	emit('on-click-item', item, index);
	!props.closePreview && onPreview(item);
};

// 删除图片
const onRemoveImage = (item: FileList, index: number): void => {
	if (!props.disabledDelete) {
		const file = props.value.filter((_item, i) => i !== index);
		emit('update:value', file);
	}
	emit('on-remove', item, index);
	formItemContext.onFieldChange();
};

const onUpdateImage = (item: FileList, index: number): void => {
	emit('on-update', item, index);
};

// 上传图片
const loading = ref<boolean>(false);
const onFileChange = async (e: any, index?: number): Promise<void> => {
	try {
		if (e.target.files.length === 0) {
			return message.error('未选择文件');
		}

		const file = e.target.files[0];
		console.log('e.target:', file);
		// 验证文件大小
		const isLt2M = file.size / 1024 / 1024 < props.maxFileSize;
		if (props.maxFileSize !== -1 && !isLt2M) {
			return message.error(`文件大小不能超过${props.maxFileSize}M`);
		}
		// 验证格式
		const postfix: string = file?.name?.split('.')?.slice(-1)[0];
		if (!props?.accept?.split(',')?.includes(postfix)) {
			return message.error(`仅支持${props?.accept}格式`);
		}

		// 验证分辨率
		if (props?.dpi) {
			try {
				await isDpi(file, props?.dpi);
			} catch (error) {
				if (typeof props?.dpi[0] === 'number') {
					const dpi = props?.dpi as [number, number];
					return message.error(`仅支持${dpi[0]}*${dpi[1]}分辨率以上的图片`);
				}
				const dpi = props?.dpi as [[number, number], [number, number]];
				if (error === -3) {
					return message.error(`仅支持${dpi[1][0]}*${dpi[1][1]}分辨率以下的图片`);
				}
				return message.error(`仅支持${props?.dpi[0][0]}*${props?.dpi[0][1]}分辨率以上的图片`);
			}
		}

		if (props.beforeUpload && !props.beforeUpload(file)) {
			e.target.value = '';
			return;
		}
		loading.value = true;
		const fileObj: FileList = {
			personName: file.name,
			status: 'loading'
		};
		const formData = new FormData();
		formData.append('files', file);
		// console.log('props.boxSerial', props);

		const param = {
			boxSerial: props.boxSerial,
			batchMark: props.count === 1 ? 0 : 1
		};
		formData.append('batchMark', JSON.stringify(param.batchMark));
		formData.append('boxSerial', props.boxSerial);
		formData.append('type', 0);

		// console.log('formData:', formData);

		const res: TsRes = await BoxManageApi.faceRecognitionImgUpload(formData);
		// fileObj.url = getRealImgUrl(data.relativeFilePath);
		console.log('res:', res.data[0]);

		fileObj.imageUrl = res.data[0];
		let fileList = props.value;
		if (index !== undefined) {
			// 替换
			fileObj.id = fileList[index].id;
			fileList[index] = props.beforeAddFileList ? props.beforeAddFileList(fileObj) : fileObj;
		} else {
			// 添加
			fileObj.id = Date.now();
			fileList.push(props.beforeAddFileList ? props.beforeAddFileList(fileObj) : fileObj);
		}
		fileObj.status = 'done';
		loading.value = false;
		emit('update:value', fileList);
		emit('on-success', fileObj, fileList);
		formItemContext.onFieldChange();
	} catch (error) {
		loading.value = false;
		emit('on-error', error);
		formItemContext.onFieldChange();
	}
};
</script>

<style lang="less" scoped>
.g-upload-image {
	display: flex;
	overflow: hidden;
	height: 100%;
	flex-wrap: wrap;
	gap: 6px;

	.card-wrap {
		height: 100%;
	}

	:deep(.ant-checkbox) {
		.ant-checkbox-inner {
			border-color: @text03 !important;
			background-color: @white !important;
		}
	}

	:deep(.ant-checkbox-checked) {
		.ant-checkbox-inner {
			border-color: @primary01 !important;
			background: @primary01 !important;
		}
	}

	.g-upload-image-list {
		display: flex;
		flex-wrap: wrap;
		gap: 6px;

		.g-upload-image-list-item {
			display: flex;
			flex-direction: column;

			.g-upload-image-item-wrap {
				position: relative;
				display: flex;
				overflow: hidden;
				width: 100%;
				height: 100%;
				border: 1px solid @borderColor02;
				border-radius: 6px;
				background: @background01;
				flex-shrink: 0;
				align-items: center;
				justify-content: center;

				.icon-loader {
					position: absolute;
					top: 50%;
					left: 50%;
					margin-top: -12px;
					margin-left: -12px;
				}

				.g-upload-image-img {
					width: 100%;
					height: 100%;
					object-fit: contain;
				}

				.g-upload-image-checkbox {
					position: absolute;
					top: 2px;
					right: 6px;
				}

				&:hover {
					.g-upload-image-operation {
						display: flex;
						align-items: center;
						justify-content: center;
					}

					.g-upload-image-checkbox[show-checkbox-hover='true'] {
						display: block !important;
					}
				}
			}

			.g-upload-image-name {
				overflow: hidden;
				height: 24px;
				font-size: 12px;
				font-weight: 400;
				line-height: 24px;
				text-align: center;
				white-space: nowrap;
				text-overflow: ellipsis;
				color: @text01;
			}

			.g-upload-image-operation {
				position: absolute;
				display: none;
				width: 100%;
				height: 100%;
				border-radius: 6px;
				background: rgba(0, 0, 0, 0.3);
				align-items: center;
				justify-content: center;
				gap: 0 12px;

				i {
					font-size: 16px;
					color: #fff;
					cursor: pointer;
				}
			}

			&.active {
				border: 2px solid @primary01;
			}
		}
	}

	.g-upload-image-wrap {
		width: 48px;
		height: 48px;

		.g-upload-image-add {
			display: flex;
			width: 100%;
			height: 100%;
			border: 1px dashed #d9d9db;
			border-radius: 6px;
			background: @background01;
			cursor: pointer;
			align-items: center;
			justify-content: center;
		}

		.icon-loader {
			display: flex;
			width: 21px;
			height: 21px;
			animation: rotate 1s linear infinite;
			align-items: center;
			justify-content: center;

			i {
				font-size: 20px;
				color: @primary01;
			}
		}

		.icon-add {
			font-size: 14px;
			text-align: center;
			color: @text02;

			i {
				font-size: 18px;
			}
		}
	}

	.g-upload-image-input {
		display: none;
	}
}
</style>
